package vip.ola.pay.channel.unionpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import vip.ola.core.common.util.MyLog;
import vip.ola.core.common.util.PayDigestUtil;
import vip.ola.core.common.util.PayUtil;
import vip.ola.core.entity.PayOrder;
import vip.ola.core.entity.PayPassageAccount;
import vip.ola.pay.channel.BasePayment;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import static vip.ola.core.common.constant.PayEnum.ERR_0010;
import static vip.ola.core.common.constant.PayEnum.ERR_0121;

@Service
public class TestPaymentService extends BasePayment {

    private static final MyLog _log = MyLog.getLog(TestPaymentService.class);

    private static final String ENCODING = "utf-8";

    @Override
    public String getChannelName() {
        return "union";
    }

    @Override
    public JSONObject pay(PayOrder payOrder) {
        try {
            _log.info("话费支付使用子账号ID：" + payOrder.getChannelMchId());
            PayPassageAccount payPassageAccount = rpcCommonService.rpcPayPassageAccountService.findById(payOrder.getPassageAccountId());
            if (payPassageAccount == null || StringUtils.isBlank(payPassageAccount.getParam())) {
                return PayUtil.makeRetFail(ERR_0121);
            }
            JSONObject accountParams = JSONObject.parseObject(payPassageAccount.getParam());
            String appKey = payPassageAccount.getPassageMchId();
            String orderId = payOrder.getPayOrderId();
            String reqUrl = accountParams.getString("payUrl");
            BigDecimal amount = new BigDecimal(payOrder.getAmount()).divide(new BigDecimal(100));
            TreeMap<String, String> map = new TreeMap<>();
            map.put("appKey",appKey);
            map.put("amount",String.valueOf(amount));
            map.put("notifyUrl",accountParams.getString("notify_url"));
            map.put("orderId",orderId);
            map.put("sign",getPrivateSign(appKey,payPassageAccount.getPrivateKey(),orderId,amount,accountParams.getString("notify_url")));
            String requestParm = reqUrl + "?" + getUrlParamsByMap(map);
            _log.info("请求信息："+requestParm);
            String respData = "{\"code\":\"000\",\"payUrl\":\"www.baidu.com\",\"state\":\"success\"}";//call(reqUrl,map);
            _log.info("下单返回={}",respData);
            int result = rpcCommonService.rpcPayOrderService.updateStatus4Ing(payOrder.getPayOrderId(), null);
            _log.info("更新订单状态为支付中: result={}", result);
            JSONObject resObj = JSON.parseObject(respData);
            if ("success".equals(resObj.getString("state")) && "000".equals(resObj.getString("code")))
            {
                String payUrl = resObj.getJSONObject("data").getString("payUrl");
                return PayUtil.makeRetPayUrl(payUrl,null);
            }else {
                String msg = resObj.getString("message");
                if ("匹配失败，请重试".equals(msg)){
                    msg = "当前支付人数较多，请重新发起支付";
                }
                return PayUtil.makeRetFail(msg);
            }
        }catch (Exception e){
            _log.error(e, "调用话费渠道异常。");
            return PayUtil.makeRetFail(ERR_0010);
        }
    }

    private String getPrivateSign(String appKey, String privateKey, String orderId, BigDecimal amount, String notifyUrl) {
        StringBuilder sb = new StringBuilder();
        String tmpStr = sb.append(appKey).append(privateKey).append(orderId).append(amount).append(notifyUrl).toString();
        _log.info("unionpay call external plateform,the request param ->{}",tmpStr);
        return  PayDigestUtil.md5(tmpStr,"UTF-8");
    }

    @Override
    public JSONObject query(PayOrder payOrder) {
        return null;
    }

    public static String getSign(Map<String,String> param, String signKey){
        SortedMap<String,String> map = new TreeMap<>(param);
        String str = "";
        map.remove("sign");
        for (Map.Entry<String,String> entry : map.entrySet()){
            if (entry.getValue() == null || "".equals(entry.getValue()) || "sign".equals(entry.getKey())){
                continue;
            }else {
                str += entry.getValue();
            }

        }
        return PayDigestUtil.md5(str+signKey,"UTF-8").toLowerCase();
    }

    public static String call(String url, Map<String,String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            _log.info("请求参数："+uri.toString());
            HttpPost httpPost = new HttpPost(uri);

            // 执行请求
            response = httpclient.execute(httpPost);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), ENCODING);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    /**
     * 将map转换成url
     *
     * @param map
     * @return
     */
    public static String getUrlParamsByMap(Map<String, String> map) {
        if (map == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            sb.append(entry.getKey() + "=" + entry.getValue());
            sb.append("&");
        }
        String s = sb.toString();
        if (s.endsWith("&")) {
            s = s.substring(0,s.length()-1);
        }
        return s;
    }
}
